import * as _ from "lodash"
import { PageList } from "../data"
import httpClient from "../httpclient"
import { Role } from "./role"
import { Store } from "./store"

export enum StaffStatus {
  Active = "active", Inactive = "inactive"
}

export enum StaffType {
  Owner = "owner", Staff = "staff"
}

export class Staff {
  public id: string
  public name: string
  public number: string
  private store_id: string
  public phone: string
  private country_code: string
  public roles: Role[] = []
  public status: StaffStatus
  public type: StaffType

  public get storeId() {
    return this.store_id
  }

  public set storeId(storeId) {
    this.store_id = storeId
  }

  public get countryCode() {
    return this.country_code
  }

  public set countryCode(countryCode) {
    this.country_code = countryCode
  }
}

class StaffQuery {
  private params = {}

  public page(page: number) {
    this.params["page"] = page
    return this
  }

  public limit(limit: number) {
    this.params["limit"] = limit
    return this
  }

  public storeId(storeId: string) {
    this.params["store_id"] = storeId
    return this
  }

  public roleIds(roleIds?: string | string[]) {
    if (_.isEmpty(roleIds)) {
      _.unset(this.params, "role_ids")
    } else {
      this.params["role_ids"] = roleIds
    }

    return this
  }

  public list(): Promise<PageList<Staff>> {
    return httpClient.get(`/v1/stores/${this.params["store_id"]}/staffs`, { params: this.params })
      .then(({ data }) => {
        return _.assign(PageList.empty(), data, {
          elements: _.map(data.elements, element => _.assign(new Staff(), element)),
        })
      })
  }
}

export class StaffServiceV1 {

  public static addStaff(staff: Staff): Promise<Staff> {
    return httpClient.post(`/v1/stores/${staff.storeId}/staffs`, staff)
      .then(({ data }) => _.assign(new Staff(), data))
  }

  public static getStaff(storeId: string, staffId: string): Promise<Staff> {
    return httpClient.get(`/v1/stores/${storeId}/staffs/${staffId}`)
      .then(({ data }) => _.assign(new Staff(), data))
  }

  public static getStaffs(): StaffQuery {
    return new StaffQuery()
  }

  public static updateStaff(staff: Staff): Promise<Staff> {
    return httpClient.patch(`/v1/stores/${staff.storeId}/staffs/${staff.id}`, staff)
      .then(({ data }) => _.assign(new Staff(), data))
  }

  public static activeStaff(storeId: string, staffId: string): Promise<void> {
    return httpClient.patch(`/v1/stores/${storeId}/staffs/${staffId}/active`)
  }

  public static inactiveStaff(storeId: string, staffId: string): Promise<void> {
    return httpClient.patch(`/v1/stores/${storeId}/staffs/${staffId}/inactive`)
  }

  public static deleteStaff(storeId: string, staffId: string): Promise<void> {
    return httpClient.delete(`/v1/stores/${storeId}/staffs/${staffId}`)
  }
}


export class StaffStore extends Store {
  public staff: Staff
}


class StaffStoreQuery {
  private params = {}

  public page(page: number) {
    this.params["page"] = page
    return this
  }

  public limit(limit: number) {
    this.params["limit"] = limit
    return this
  }

  public storeId(storeId: string) {
    this.params["store_id"] = storeId
    return this
  }

  public staffIds(staffIds?: string | string[]) {
    if (_.isEmpty(staffIds)) {
      _.unset(this.params, "staff_ids")
    } else {
      this.params["staff_ids"] = staffIds
    }

    return this
  }

  public list(): Promise<PageList<StaffStore>> {
    return httpClient.get(`/v1/staffs/stores`, { params: this.params })
      .then(({ data }) => {
        return _.assign(PageList.empty(), data, {
          elements: _.map(data.elements, element => _.assign(new StaffStore(), element, {
            staff: _.assign(new Staff(), element.staff),
          })),
        })
      })
  }
}


export class StaffStoreServiceV1 {
  public static getStaffStores(): StaffStoreQuery {
    return new StaffStoreQuery()
  }
}
